package org.changs.nav.ui.set;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.amap.api.maps.AMapException;
import com.amap.api.maps.offlinemap.OfflineMapCity;
import com.amap.api.maps.offlinemap.OfflineMapManager;
import com.amap.api.maps.offlinemap.OfflineMapProvince;
import com.amap.api.maps.offlinemap.OfflineMapStatus;

import org.changs.nav.R;
import org.changs.nav.databinding.ItemOfflineMapCityBinding;
import org.changs.nav.databinding.ItemOfflineMapProvinceBinding;
import org.changs.nav.databinding.ItemOfflineMapProvinceOnlyoneBinding;
import org.changs.nav.databinding.ItemOfflineMapWholeCityBinding;
import org.changs.nav.databinding.MainOfflineMapDownloadFragmentBinding;
import org.changs.nav.ui.nav.BaseMapFragment;

import java.util.ArrayList;
import java.util.List;

import timber.log.Timber;

/**
 * Created by yincs on 2017/8/31.
 */

public class OfflineMapFragment extends BaseMapFragment {

    private static final String WHOLE_CITY_NAME = "全省地图";
    private MainOfflineMapDownloadFragmentBinding mBinding;
    private OfflineMapManager mOfflineMapManager;

    @Override
    public View setup(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinding = DataBindingUtil.inflate(inflater, R.layout.main_offline_map_download_fragment, container, false);
        initUI();
        showLoading().setMessage("正在加载离线地图");
        mOfflineMapManager = new OfflineMapManager(getContext(), new OfflineMapManager.OfflineMapDownloadListener() {
            @Override
            public void onDownload(int status, int completeCode, String downName) {
                Timber.d("onDownload() called with: " + "status = [" + status + "], completeCode = [" + completeCode + "], downName = [" + downName + "]");
                mBinding.rccAllCity.getAdapter().notifyDataSetChanged();
            }

            @Override
            public void onCheckUpdate(boolean hasNew, String name) {
                Timber.d("onCheckUpdate() called with: " + "hasNew = [" + hasNew + "], name = [" + name + "]");
                mBinding.rccAllCity.getAdapter().notifyDataSetChanged();
            }

            @Override
            public void onRemove(boolean success, String name, String describe) {
                Timber.d("onRemove() called with: " + "success = [" + success + "], name = [" + name + "], describe = [" + describe + "]");
                mBinding.rccAllCity.getAdapter().notifyDataSetChanged();
            }
        });
        mOfflineMapManager.setOnOfflineLoadedListener(() -> {
            Timber.d("onVerifyComplete() called");
            initData();
            hideLoading();
        });
        return mBinding.getRoot();
    }


    private void initUI() {

    }

    private void initData() {
        mBinding.rccAllCity.setLayoutManager(new LinearLayoutManager(getContext()));
        MyAdapter adapter = new MyAdapter();
        mBinding.rccAllCity.setAdapter(adapter);

        OfflineMapProvince wholeOutline = new OfflineMapProvince();
        wholeOutline.setCityList(new ArrayList<>());
        wholeOutline.setProvinceName("基础功能包");
        OfflineMapProvince directCity = new OfflineMapProvince();
        directCity.setCityList(new ArrayList<>());
        directCity.setProvinceName("直辖市");
        OfflineMapProvince especialCity = new OfflineMapProvince();
        especialCity.setCityList(new ArrayList<>());
        especialCity.setProvinceName("特别行政区");

        ArrayList<OfflineMapProvince> offlineMapProvinceList = mOfflineMapManager.getOfflineMapProvinceList();
        Timber.d("offlineMapProvinceList.size() = " + offlineMapProvinceList.size());
        for (OfflineMapProvince offlineMapProvince : offlineMapProvinceList) {
            if (offlineMapProvince.getCityList().size() != 1) {
                adapter.getData().add(offlineMapProvince);
            } else {
                String name = offlineMapProvince.getProvinceName();
                if (name.contains("香港") || name.contains("澳门")) {
                    especialCity.getCityList().addAll(offlineMapProvince.getCityList());
                } else if (name.contains("全国概要图")) {
                    wholeOutline.getCityList().addAll(offlineMapProvince.getCityList());
                } else {
                    directCity.getCityList().addAll(offlineMapProvince.getCityList());
                }
            }
        }
        adapter.getData().add(0, wholeOutline);
        adapter.getData().add(1, directCity);
        adapter.getData().add(especialCity);
    }

    private class MyAdapter extends RecyclerView.Adapter {
        private static final int TYPE_PROVINCE_ONLYONE = 2;
        private static final int TYPE_PROVINCE = 1;
        private static final int TYPE_CITY = 0;
        private static final int TYPE_ALL_CITY = -1;

        private List<Object> mData = new ArrayList<>();

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = getContext().getLayoutInflater();
            if (viewType == TYPE_PROVINCE) {
                ItemOfflineMapProvinceBinding binding = DataBindingUtil.inflate(inflater,
                        R.layout.item_offline_map_province, parent, false);
                return new MyProvinceViewHolder(binding);
            } else if (viewType == TYPE_CITY) {
                ItemOfflineMapCityBinding binding = DataBindingUtil.inflate(inflater,
                        R.layout.item_offline_map_city, parent, false);
                return new MyCityViewHolder(binding);
            } else if (viewType == TYPE_PROVINCE_ONLYONE) {
                ItemOfflineMapProvinceOnlyoneBinding binding = DataBindingUtil.inflate(inflater,
                        R.layout.item_offline_map_province_onlyone, parent, false);
                return new MyProvinceViewHolderOnlyone(binding);
            } else if (viewType == TYPE_ALL_CITY) {
                ItemOfflineMapWholeCityBinding binding = DataBindingUtil.inflate(inflater,
                        R.layout.item_offline_map_whole_city, parent, false);
                return new MyWholeCityViewHolder(binding);
            }
            throw new RuntimeException("viewType = " + viewType + ",没有返回该ViewHolder");
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            final int itemViewType = getItemViewType(position);
            if (itemViewType == TYPE_PROVINCE) {
                OfflineMapProvince offlineMapProvince = (OfflineMapProvince) getData().get(position);
                MyProvinceViewHolder myProvinceViewHolder = (MyProvinceViewHolder) holder;
                myProvinceViewHolder.binding.tvProvinceName.setText(offlineMapProvince.getProvinceName());
                myProvinceViewHolder.binding.ivIcon.setImageResource(isExpanded(position) ? R.mipmap.directions_more_up_black : R.mipmap.directions_more_down_black);
                myProvinceViewHolder.binding.getRoot().setOnClickListener(v -> {
                    ArrayList<OfflineMapCity> cityList = offlineMapProvince.getCityList();
                    if (!isExpanded(position)) {
                        getData().addAll(position + 1, cityList);
                        final int aim = position + 3;
                        mBinding.rccAllCity.smoothScrollToPosition(aim > getData().size() - 1 ? getData().size() - 1 : aim);
                    } else {
                        getData().removeAll(cityList);
                    }
                    notifyDataSetChanged();
                });
            } else if (itemViewType == TYPE_PROVINCE_ONLYONE) {
                OfflineMapProvince offlineMapProvince = (OfflineMapProvince) getData().get(position);
                MyProvinceViewHolderOnlyone myProvinceViewHolder = (MyProvinceViewHolderOnlyone) holder;
                myProvinceViewHolder.binding.tvProvinceName.setText(offlineMapProvince.getProvinceName());
                setupCity(offlineMapProvince.getCityList().get(0), myProvinceViewHolder.itemView, myProvinceViewHolder.binding.tvProvinceName,
                        myProvinceViewHolder.binding.btnState, myProvinceViewHolder.binding.tvState,
                        myProvinceViewHolder.binding.tvPercent, myProvinceViewHolder.binding.tvSize);
            } else if (itemViewType == TYPE_CITY) {
                OfflineMapCity offlineMapCity = (OfflineMapCity) getData().get(position);
                MyCityViewHolder myProvinceViewHolder = (MyCityViewHolder) holder;
                setupCity(offlineMapCity, myProvinceViewHolder.itemView, myProvinceViewHolder.binding.tvProvinceName,
                        myProvinceViewHolder.binding.btnState, myProvinceViewHolder.binding.tvState,
                        myProvinceViewHolder.binding.tvPercent, myProvinceViewHolder.binding.tvSize);
            } else if (itemViewType == TYPE_ALL_CITY) {
                MyWholeCityViewHolder myWholeCityViewHolder = (MyWholeCityViewHolder) holder;
                OfflineMapProvince offlineMapProvince = (OfflineMapProvince) getData().get(position - 1);
                myWholeCityViewHolder.binding.tvSize.setText(String.format("%.1fM", offlineMapProvince.getSize() / 1024.0 / 1024.0));
                final boolean isSuccess = offlineMapProvince.getState() == OfflineMapStatus.SUCCESS;
                myWholeCityViewHolder.binding.btnStartAll.setEnabled(!isSuccess);
                myWholeCityViewHolder.binding.btnStopAll.setEnabled(isSuccess);
                myWholeCityViewHolder.binding.btnStartAll.setOnClickListener(v -> {
                    try {
                        mOfflineMapManager.downloadByProvinceName(offlineMapProvince.getProvinceName());
                    } catch (AMapException e) {
                        e.printStackTrace();
                    }
                });
                myWholeCityViewHolder.binding.btnStopAll.setOnClickListener(v -> {
                    mOfflineMapManager.stop();
                });

            }
        }

        private void setupCity(OfflineMapCity offlineMapCity, View root, TextView tvName, TextView btnState, TextView tvState, TextView tvPercent, TextView tvSize) {
            final int state = offlineMapCity.getState();
            Timber.d("offlineMapCity.getCity() = " + offlineMapCity.getCity() + ";state = " + state);
            tvName.setText(offlineMapCity.getCity());
            switch (state) {
                case OfflineMapStatus.EXCEPTION_NETWORK_LOADING:
                case OfflineMapStatus.EXCEPTION_AMAP:
                case OfflineMapStatus.EXCEPTION_SDCARD:
                case OfflineMapStatus.CHECKUPDATES://默认状态
                case OfflineMapStatus.ERROR://默认状态
                    btnState.setText("下载");
                    btnState.setBackgroundResource(R.drawable.round100_green_deep);
                    btnState.setVisibility(View.VISIBLE);
                    tvPercent.setVisibility(View.GONE);
                    tvState.setVisibility(View.GONE);
                    break;
                case OfflineMapStatus.LOADING://正在下载
                    btnState.setText("暂停");
                    btnState.setBackgroundResource(R.drawable.round100_primary_deep);
                    btnState.setVisibility(View.VISIBLE);
                    tvPercent.setVisibility(View.VISIBLE);
                    tvState.setVisibility(View.GONE);
                    break;
                case OfflineMapStatus.PAUSE://暂停下载
                    btnState.setText("继续");
                    btnState.setBackgroundResource(R.drawable.round100_primary_deep);
                    btnState.setVisibility(View.VISIBLE);
                    tvPercent.setVisibility(View.VISIBLE);
                    tvState.setVisibility(View.GONE);
                    break;
                case OfflineMapStatus.WAITING://等待下载
                    tvState.setText("等待中");
                    tvPercent.setVisibility(View.VISIBLE);
                    btnState.setVisibility(View.GONE);
                    tvState.setVisibility(View.VISIBLE);
                    break;
                case OfflineMapStatus.UNZIP://正在解压
                    tvState.setText("正在解压");
                    tvPercent.setVisibility(View.VISIBLE);
                    btnState.setVisibility(View.GONE);
                    tvState.setVisibility(View.VISIBLE);
                    break;
                case OfflineMapStatus.SUCCESS://下载成功
                    tvState.setText("已下载");
                    tvPercent.setVisibility(View.GONE);
                    btnState.setVisibility(View.GONE);
                    tvState.setVisibility(View.VISIBLE);
                    break;
            }

            tvPercent.setText(String.format("%d%%", offlineMapCity.getcompleteCode()));
            tvSize.setText(String.format("%.1fM", offlineMapCity.getSize() / 1024.0 / 1024.0));
            btnState.setOnClickListener(v -> {
                final String text = btnState.getText().toString();
                if (text.equals("下载")) {
                    try {
                        mOfflineMapManager.downloadByCityName(offlineMapCity.getCity());
                    } catch (AMapException e) {
                        e.printStackTrace();
                        Timber.d("e.getErrorMessage() = " + e.getErrorMessage());
                    }
                } else if (text.equals("暂停")) {
                    mOfflineMapManager.pause();
                    mOfflineMapManager.restart();
                } else if (text.equals("继续")) {
                    try {
                        mOfflineMapManager.downloadByCityName(offlineMapCity.getCity());
                    } catch (AMapException e) {
                        e.printStackTrace();
                        Timber.d("e.getErrorMessage() = " + e.getErrorMessage());
                    }
                }
                notifyDataSetChanged();
            });
        }

        @Override
        public int getItemCount() {
            return mData.size();
        }

        @Override
        public int getItemViewType(int position) {
            Object data = mData.get(position);
            if (data instanceof OfflineMapProvince) {
                final OfflineMapProvince province = (OfflineMapProvince) data;
                if (province.getCityList().size() == 1) {
                    return TYPE_PROVINCE_ONLYONE;
                }
                return TYPE_PROVINCE;
            } else if (data instanceof OfflineMapCity) {
                if (WHOLE_CITY_NAME.equals(((OfflineMapCity) data).getCity())) {
                    return TYPE_ALL_CITY;
                }
                return TYPE_CITY;
            }
            throw new RuntimeException("没有实现 getItemViewType():" + position);
        }

        private boolean isExpanded(int position) {
            if (position + 1 >= getData().size())
                return false;
            Object nextData = getData().get(position + 1);
            return !(nextData == null || nextData instanceof OfflineMapProvince);
        }

        public List<Object> getData() {
            return mData;
        }

        private class MyProvinceViewHolder extends RecyclerView.ViewHolder {

            private final ItemOfflineMapProvinceBinding binding;

            public MyProvinceViewHolder(ItemOfflineMapProvinceBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }

        private class MyCityViewHolder extends RecyclerView.ViewHolder {

            private final ItemOfflineMapCityBinding binding;

            public MyCityViewHolder(ItemOfflineMapCityBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }

        private class MyWholeCityViewHolder extends RecyclerView.ViewHolder {

            private final ItemOfflineMapWholeCityBinding binding;

            public MyWholeCityViewHolder(ItemOfflineMapWholeCityBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }

        private class MyProvinceViewHolderOnlyone extends RecyclerView.ViewHolder {

            private final ItemOfflineMapProvinceOnlyoneBinding binding;

            public MyProvinceViewHolderOnlyone(ItemOfflineMapProvinceOnlyoneBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }
    }
}
